package be.sc.classicnetwork.service.impl;

import java.util.Collection;
import java.util.HashSet;

import org.springframework.transaction.annotation.Transactional;

import be.sc.classicnetwork.annotation.RefreshCache;
import be.sc.classicnetwork.dao.CarDao;
import be.sc.classicnetwork.dao.GenericDao;
import be.sc.classicnetwork.dao.PaginationSearchResult;
import be.sc.classicnetwork.model.Car;
import be.sc.classicnetwork.model.Contact;
import be.sc.classicnetwork.model.Image;
import be.sc.classicnetwork.model.Make;
import be.sc.classicnetwork.model.Option;
import be.sc.classicnetwork.service.CarService;
import be.sc.classicnetwork.service.ServiceLocator;
import be.sc.classicnetwork.util.Assert;

/**
 * CarService implementation.
 */
@Transactional
public class CarServiceImpl extends GenericServiceImpl<Car> implements CarService {

    private ServiceLocator serviceLocator;

    /**
     * Constructor.
     */
    public CarServiceImpl(GenericDao<Car> dao) {
	super(dao);
    }

    /**
     * getCarDao.
     */
    private CarDao getCarDao() {
	return (CarDao) getDao();
    }

    /**
     * @see be.sc.classicnetwork.service.impl.GenericServiceImpl#findByIdFull(int)
     *      TODO this was done for AOP; find another way (without writing this
     *      method)
     */
    @Override
    public Car findByIdFull(String id) {
	return super.findByIdFull(id);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#saveOrUpdate(Car, Image[],
     *      Option[])
     */
    @RefreshCache(cacheRegion = RefreshCache.CARS)
    public Car saveOrUpdate(Car car, Image[] images2delete, Collection<Option> options) {
	Assert.notNull(images2delete);
	Assert.notNull(options);

	car.removeImages(images2delete);
	car.setOptions(new HashSet<Option>(options));
	car.addDefaultImageIfNone();
	car.setThumbIfNone();

	return super.saveOrUpdate(car);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#countMakes(boolean)
     */
    public Collection<Object[]> countMakes(boolean enableFilterPublished) {
	return getCarDao().countMakes(enableFilterPublished);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#findByMake(int, int,
     *      boolean, be.sc.classicnetwork.model.Make)
     */
    public PaginationSearchResult findByMake(int first, int max, boolean enableFilterPublished, Make make) {
	return getCarDao().findByMake(first, max, enableFilterPublished, make);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#findByModelOrMakeLike(int,
     *      int, boolean, java.lang.String)
     */
    public PaginationSearchResult findByModelOrMakeLike(int offset, int maxPageItems, boolean enableFilterPublished,
	    String model) {
	return getCarDao().findByModelOrMakeLike(offset, maxPageItems, enableFilterPublished, model);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#findImageById(int)
     */
    public Image findImageById(String id) {
	return getCarDao().findImageById(id);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#findContactsForNotification(int)
     */
    public Collection<Contact> findContactsForNotification(String carId) {
	return getCarDao().findContactsForNotification(carId);
    }

    /**
     * @see be.sc.classicnetwork.service.CarService#findAll(int, int, boolean)
     */
    public PaginationSearchResult findAll(int first, int max, boolean enableFilterPublished) {
	return getCarDao().findAll(first, max, enableFilterPublished);
    }

    public ServiceLocator getServiceLocator() {
	return serviceLocator;
    }

    public void setServiceLocator(ServiceLocator serviceLocator) {
	this.serviceLocator = serviceLocator;
    }

}
